package com.vadmin.vadminjava.service;

import com.alibaba.fastjson.JSONObject;
import com.vadmin.vadminjava.aes.WXBizJsonMsgCrypt;
import com.vadmin.vadminjava.aes.WXBizMsgCrypt;
import com.vadmin.vadminjava.common.LogEnum;
import com.vadmin.vadminjava.common.ResultSetToJavaBean;
import com.vadmin.vadminjava.common.WxWorkConfig;
import com.vadmin.vadminjava.common.xmlTool;
import com.vadmin.vadminjava.db.DBUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;


/* ***********************************************************
 *
 * 企业微信的【通讯录变更】回调通知接收相关处理
 *
 * **********************************************************/
@Component
public class WxWorkNotifyWorkerService {

	org.slf4j.Logger logger = LoggerFactory.getLogger(WxWorkNotifyWorkerService.class.getName());

	@Autowired
	AdminLogService adminLogService;

	//回调处理入口函数
	public String WorkerUserChange(JSONObject paramJ, String sReqData){

		//配置
		String sCorpID         = WxWorkConfig.CORP_ID;//企业id，在我的企业标签页里面
		String sToken          = WxWorkConfig.WORKER_STOKEN;//设置接收事件服务器时的参数有
		String sEncodingAESKey = WxWorkConfig.WORKER_SENCODINGAESKEY;//设置接收事件服务器时的参数有

		String sEchoStr = ""; //验证url时需要返回的明文

		try {
			WXBizJsonMsgCrypt wxcptJSON = new WXBizJsonMsgCrypt(sToken, sEncodingAESKey, sCorpID);//验证时用的，按json数据处理
			WXBizMsgCrypt     wxcptXML  = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);//推送消息用的，是xml数据处理方式

			// 解析出url上的参数值如下：
			String msgSignature = paramJ.getString("msg_signature");
			String timestamp    = paramJ.getString("timestamp");
			String nonce        = paramJ.getString("nonce");//随机数
			String echostr      = paramJ.getString("echostr");//加密的字符串。验证url时才有发送

			//判断是否是url验证，否则就是正式通知(狗日的企业微信后台保存回调域名时，是要先验证的)
			if(StringUtils.isNotEmpty(echostr)){
				sEchoStr = wxcptJSON.VerifyURL(msgSignature, timestamp, nonce, echostr);
				logger.info("进行了通讯录变更回调url设置的验证,返回的明文是："+sEchoStr);
			}else{

				//System.out.println("原始post数据流："+sReqData);
				String sMsg = wxcptXML.DecryptMsg(msgSignature, timestamp, nonce, sReqData);
				logger.info("解密之后: " + sMsg);//2022-05-06由sout改为logger
				Map<String,String> xmlParse = xmlTool.xmlToMap(sMsg);
				logger.info("通讯录变更回调转成map："+xmlParse);//2022-05-06由sout改为logger
				sEchoStr = xmlParse.toString();
				//进行处理
				WorkerUserDataHandle(xmlParse);
			}

		} catch (Exception ex) {
			logger.error("通讯录变更回调过程出错了{}",ex);
			sEchoStr = "通讯录变更回调过程出错了" + ex.getMessage();
		} finally {

		}

		return sEchoStr;
	}


	//dev,sReqData直接传解密后的xml进来
	public String WorkerUserChangeDev(JSONObject paramJ, String sReqData){
		String sEchoStr = ""; //验证url时需要返回的明文
		try {
			System.out.println("解密之后: " + sReqData);
			Map<String,String> xmlParse = xmlTool.xmlToMap(sReqData);
			System.out.println("转成map："+xmlParse);
			sEchoStr = xmlParse.toString();
			//进行处理
			WorkerUserDataHandle(xmlParse);
		} catch (Exception ex) {
			logger.error("通讯录变更回调过程出错了{}",ex);
		} finally {
		}
		return sEchoStr;
	}

	// 成员数据处理
	public void WorkerUserDataHandle(Map<String,String> xmlParse){
		DBUtil dbUtil = new DBUtil();
		adminLogService.write(LogEnum.WORKER_EVENT.getName(), LogEnum.WORKER_EVENT.getIndex(), JSONObject.toJSONString(xmlParse).replaceAll("[{}]",""));
		//得到相关数据
		String changeType      = xmlParse.get("ChangeType");//类型
		String userId          = xmlParse.get("UserID"); //标识id,
		String newUserID       = xmlParse.get("NewUserID"); //新的UserID，变更时推送,
		String name            = xmlParse.get("Name"); //'员工姓名',
		String mobile          = xmlParse.get("Mobile"); //'手机',手机号码，变更时推送
		String department      = xmlParse.get("Department"); //'成员部门列表，变更时推送',
		String position        = xmlParse.get("Position"); //'职位信息。长度为0~64个字节，变更时推送',
		String gender          = xmlParse.get("Gender"); //'性别，变更时推送。',
		String avatar          = xmlParse.get("Avatar"); //'头像url。注：如果要获取小图将url最后的”/0”改成”/100”即可。变更时推送。',
		String mainDepartment = xmlParse.get("MainDepartment"); //'主部门'，经测试，改了才会推送,



		try {
			//进行类型判断
			if(changeType.equals("create_user")){//新增
				//判断是否已经有数据
				String sql = "select count(id) as count1 from wxwork_user where user_id='"+userId+"'";//获取行数
				Integer count = ResultSetToJavaBean.copyJsonSingleQuery(dbUtil, sql).getInteger("count1");
				if(count==0){
					//写入数据库
					//通用插入sql
					String sqlInserUer = "INSERT INTO `wxwork_user`( `user_id`, `name`,`mobile`, `department`, `position`, `gender`, `avatar`, `main_department`,`update_time`) " +
							"VALUES ('"+userId+"', '"+name+"', '"+mobile+"','"+department+"', '"+position+"', '"+gender+"', '"+avatar+"', '"+mainDepartment+"',NOW())";
					System.out.println("员工数据sql："+sqlInserUer);
					dbUtil.insertOrUpdateInfoTONum(sqlInserUer);
					logger.info("通讯录变更回调处理>>>>>>，类型是{},创建了员工表数据！数据：{}",changeType,xmlParse.toString() );
					adminLogService.write(LogEnum.WORKER_ADD.getName(), LogEnum.WORKER_ADD.getIndex(), JSONObject.toJSONString(xmlParse).replaceAll("[{}]",""));

				}else{
					logger.info("通讯录变更回调处理>>>>>>，类型是{},已经存在员工数据，不重复创建。数据：{}",changeType,xmlParse.toString() );
				}


			}else if(changeType.equals("delete_user")){//删除
				//根据任务来处理，目前只更新remove字段标识一下
				String sql = "update wxwork_user set remove = '1' where user_id = '"+userId+"'";
				dbUtil.executeUpdateTOnum(sql);

				logger.info("通讯录变更回调处理>>>>>>，类型是{},删除员工。数据：{}",changeType,xmlParse.toString() );
				adminLogService.write(LogEnum.WORKER_DEL.getName(), LogEnum.WORKER_DEL.getIndex(), JSONObject.toJSONString(xmlParse).replaceAll("[{}]",""));

			}else if(changeType.equals("update_user")){//更新资料 经测试，不是所有字段都会推送过来的，会造成null,需要进行sql组合

				String sqlUd = "UPDATE `wxwork_user` SET ";
				if(name != null)           sqlUd += "`name` = '" + name + "',";//测试通过
				if(mobile != null)         sqlUd += "`mobile` = '" + mobile + "',";//未测
				if(department != null)     sqlUd += "`department` = '" + department + "',";//测试通过
				if(position != null)       sqlUd += "`position` = '" + position + "',";//测试通过
				if(gender != null)         sqlUd += "`gender` = '" + gender + "',";//测试通过
				if(avatar != null)         sqlUd += "`avatar` = '" + avatar + "',";//测试通过
				if(mainDepartment != null) sqlUd += "`main_department` = '" + mainDepartment + "',";//测试通过
				if(newUserID != null)      sqlUd += "`user_id` = '" + newUserID + "',";//

				sqlUd += " `update_time` =NOW()  WHERE `user_id` = '"+userId+"'";
				System.out.println(sqlUd);
				dbUtil.insertOrUpdateInfoTONum(sqlUd);

				logger.info("通讯录变更回调处理>>>>>>，类型是{},更改员工信息。数据：{}",changeType,xmlParse.toString() );
				String logText = JSONObject.toJSONString(xmlParse).replaceAll("[{}]", "");

				//如果改的是id，则要进行其它处理（详见任务）
				if(newUserID != null){
					//更新外部客户表的userid字段(这个字段没什么用，不能用来关联查询)
					String sql2 = "update wxwork_external_user set userid = '"+newUserID+"' where userid='"+userId+"'";
					dbUtil.insertOrUpdateInfoTONum(sql2);
					//关系表的 todo 2022-03-29加入，未进行测试
					String sql3 = "update wxwork_relation set userid = '"+newUserID+"' where userid='"+userId+"'";
					dbUtil.insertOrUpdateInfoTONum(sql3);
					//资金明细表的 todo 2022-03-29加入，未进行测试
					String sql4 = "update wxwork_user_money_log set user_id = '"+newUserID+"' where userid='"+userId+"'";
					dbUtil.insertOrUpdateInfoTONum(sql4);

					logger.info("通讯录变更回调处理>>>>>>并且旧的userid：{}改为了：{}",userId,newUserID);
					logText = "旧的userid:"+userId+"改为了:"+newUserID + "。涉及表：wxwork_user，wxwork_external_user，wxwork_relation，wxwork_user_money_log。推送数据："+ logText;
				}

				adminLogService.write(LogEnum.WORKER_UPDATE.name, LogEnum.WORKER_UPDATE.index, logText);
			}

		} catch (Exception ex) {
			logger.error("处理员工变更回调数据时出错了:{},回调数据：{}",ex,xmlParse);
		} finally {
			dbUtil.closeNoErr();
		}
	}
}

